package cn.mjnxin.iot.connector.handle;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import cn.mjnxin.iot.base.cache.LocalCache;
import cn.mjnxin.iot.base.log.LogWorker;
import cn.mjnxin.iot.connector.coder.Gate2HostDecoder;
import cn.mjnxin.iot.connector.coder.Host2GateEncoder;
import cn.mjnxin.iot.connector.context.ConnectorContext;
import cn.mjnxin.iot.connector.context.IPeerChangedListener;
import cn.mjnxin.iot.connector.context.IPeerContext;
import cn.mjnxin.iot.connector.message.IMessage;
import cn.mjnxin.iot.connector.message.IMessageHandle;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInboundHandler;

/**
 * 缺省实现
 * @author CLG 2023年10月10日
 * @version V1.0.0
 */
public class DefaultMessageHandleFactory implements IHandleFactory, IPeerChangedListener {
    // <pid, IMessageHandle>
    private static Map<Integer, IMessageHandle<?>>   allHandleMap     = new HashMap<>();
    protected static Map<Integer, IMessageHandle<?>> messageHandleMap = new HashMap<>();
    protected final IPeerContext                context;

    public DefaultMessageHandleFactory(IPeerContext context) {
        this.context = context;
    }

    public void startMQListener() {
    }

    public void stopMQListener() {
    }

    @Override
    public void initAllMessageHandle(Integer[] pidArray) {
        for(int pid : pidArray) {
        	if (allHandleMap.containsKey(pid)) {
                messageHandleMap.put(pid, allHandleMap.get(pid));
        	}
            
            LogWorker.logForce(String.format("联网协议 %d 还未实现!", pid));
        }
    }

	@Override
	public void registMessageHandle(IMessageHandle<? extends IMessage<?>> messageHandle) {
		allHandleMap.put(messageHandle.getPid(), messageHandle);
	}
    
    @Override
    public IMessageHandle<? extends IMessage<?>> getMessageHandle(Integer pid) {
        final IMessageHandle<?> messageHandle = messageHandleMap.get(pid);

        if (messageHandle == null) {
            LogWorker.logForce(String.format("%s联网协议 %d 还未实现!", ConnectorContext.PEER_NAME, pid));
            throw new NullPointerException(String.format("不支持的%s联网协议类型 %d", ConnectorContext.PEER_NAME, pid));
        }

        return messageHandle;
    }

    public static Set<Integer> allSupportPid() {
    	return messageHandleMap.keySet();
    }
    
    @Override
    public void onRemovePeer(Integer pid, String terminalAddress, LocalCache deviceCache) {
    	if (deviceCache == null) {
    		return;
    	}
        String deviceNo = deviceCache.toString();
        if (deviceNo == null) {
            LogWorker.logForce("onRemovePeer: " + ConnectorContext.PEER_NAME + "缓存未初始化");
            return;
        }
        IMessageHandle<? extends IMessage<?>> messageHandle = getMessageHandle(pid);
        messageHandle.onPeerOffline(terminalAddress, deviceNo, ConnectorContext.PEER_NAME + "主动断网", false);
    }
    
    @Override
    public void onClosePeer(Integer pid, String terminalAddress, LocalCache deviceCache) {
    	if (deviceCache == null) {
    		return;
    	}
        String deviceNo = deviceCache.toString();
        if (deviceNo == null) {
            LogWorker.logForce("onClosePeer: " + ConnectorContext.PEER_NAME + "缓存未初始化");
            return;
        }
        IMessageHandle<? extends IMessage<?>> messageHandle = getMessageHandle(pid);
        messageHandle.onPeerOffline(terminalAddress, deviceNo, ConnectorContext.CONNECTOR_NAME + "断开" + ConnectorContext.PEER_NAME, false);
    }

    @Override
    public void unlinkPeer(Integer pid, String terminalAddress, String deviceNo) {
        IMessageHandle<? extends IMessage<?>> messageHandle = getMessageHandle(pid);
        messageHandle.onPeerOffline(terminalAddress, deviceNo, "网络断连，等待" + ConnectorContext.PEER_NAME + "重新联网", false);
    }

	@Override
	public void onKickoutPeer(Integer pid, String terminalAddress, LocalCache deviceCache) {
    	if (deviceCache == null) {
    		return;
    	}
        String deviceNo = deviceCache.toString();
        if (deviceNo == null) {
            LogWorker.logForce("onKickoutPeer: " + ConnectorContext.PEER_NAME + "缓存未初始化");
            return;
        }
        IMessageHandle<? extends IMessage<?>> messageHandle = getMessageHandle(pid);
        messageHandle.onPeerOffline(terminalAddress, deviceNo, "超时6分钟不发报文判定离线", true);
    }

	@Override
	public void changePeerLink(Integer pid, String oldAddress, String terminalAddress, String deviceNo) {
        IMessageHandle<? extends IMessage<?>> messageHandle = getMessageHandle(pid);
        messageHandle.changePeerLink(oldAddress, terminalAddress, deviceNo);
	}

	@Override
	public ChannelHandler[] getChannelHandlers(ChannelInboundHandler thisHandle, Integer pid, Integer logLevel, boolean isAllMatch) {
		ConnectorAsClient2GateInHandler connectorAsClient4GateInHandler = new ConnectorAsClient2GateInHandler(context);
		return new ChannelHandler[]{
			new Gate2HostDecoder(isAllMatch, pid, logLevel, context),
			new Host2GateEncoder(logLevel),
			thisHandle,
			connectorAsClient4GateInHandler
		};
	}

	@Override
	public ByteBuf getLoginBuf(Integer gateNo, Integer pid, String localAddress, boolean mngMode, boolean isAllMatch) throws Exception {
		return null;
	}

	@Override
	public void onConnectSuccess(String ip, Integer port, Integer pid) {
		
	}

	@Override
	public void onConnectFailed(String ip, Integer port, Integer pid) {
		
	}
}
